import asyncio
import time
from datetime import datetime

import socketio
from fastapi import HTTPException, status, Depends
from typing import Dict, Any, List, Optional
from sqlalchemy.orm import Session

from common.RsaUtil import RsaUtil
from common.sqlalchemy_db import SqlalchemyX
from modules.mod import Message, Socket
from service.DialogService import DialogService
from service.GroupDBService import GroupDBService
from service.GroupService import GroupService
from service.MessageService import MessageService
from service.SocketService import SocketService
from service.UserService import UserService


class ChattingMessageService:
    def __init__(
        self,
        message_service: MessageService = MessageService(),
        user_service: UserService = UserService(),
        socket_service: SocketService = SocketService(),
        _group_service: GroupDBService = GroupDBService(),
        dialog_service: DialogService = DialogService(),
        group_service: GroupService = GroupService(),
        db: Session = Depends(SqlalchemyX.get_db)
    ):
        self.message_service = message_service
        self.user_service = user_service
        self.socket_service = socket_service
        self._group_service = _group_service
        self.dialog_service = dialog_service
        self.group_service = group_service
        self.db  = db

    async def get_history_messages(self,dialog_id: int, page: int, limit: int) -> Dict[str, Any]:
        dialog = await self.dialog_service.check_and_get_dialog_mes({"dialog_id": dialog_id})
        dialog_target_type = await self.dialog_service.get_dialog_target_type(dialog)
        history_mes_limit = await self.get_history_message_by_target_type(
            dialog_target_type,
            dialog,
            {"skip": (page - 1) * limit, "take": limit, "order": {"message_created_time": "DESC"}}
        )
        history_mes_all = await self.get_history_message_by_target_type(dialog_target_type, dialog)
        all_message_count = len(history_mes_all)
        history_messages = await self.resolve_history_message(history_mes_limit)
        return {
            "error_code": 0,
            "data": {
                "curPage": page,
                "messageNum": len(history_mes_limit),
                "pageSum": all_message_count // limit + 1,
                "historyMessages": history_messages
            }
        }

    async def get_default_group_history_messages(self, page: int, limit: int) -> Dict[str, Any]:
        default_group = await self._group_service.get_default_group()
        default_group_id = default_group.group_id
        history_mes_limit = await self.message_service.find_message_by_option({
            "where": {"message_to_id": default_group_id},
            "order": {"message_created_time": "DESC"},
            "skip": (page - 1) * limit,
            "take": limit
        })
        resolved_history_message = await self.resolve_history_message(history_mes_limit)
        all_message_count = len(await self.message_service.find_message_by_option({
            "where": {"message_to_id": default_group_id}
        }))
        return {
            "error_code": 0,
            "data": {
                "curPage": page,
                "messageNum": len(history_mes_limit),
                "pageSum": all_message_count // limit + 1,
                "historyMessages": resolved_history_message
            }
        }

    async def send_message(self, message: dict, sid, socket: socketio.AsyncServer) -> Dict[str, Any]:
        message_from_id = message["message_from_id"]
        message_to_id = message["message_to_id"]
        message_type = message["message_type"]
        # 对客户端已经通过AES加密的数据，进行二次RSA加密，使用单独的密钥
        message_content = message["message_content"]
        message_content_type = message["message_content_type"]

        message["message_created_time"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        message["message_state"] = 1

        message_id = None
        message_target = None

        message_from_basic = await self.user_service.get_user_basic_mes({"user_id": message_from_id})
        message_from_name = message_from_basic["user_name"]
        message_from_avatar = message_from_basic["user_avatar"]
        message_from_state = message_from_basic["user_state"]

        # 私聊
        if message_type == 0:
            if not await self.user_service.check_user_existence({"user_id": message_to_id}):
                raise RuntimeError(
                    "目标用户不存在"
                )

            user_basic = await self.user_service.get_user_basic_mes({"user_id": message_to_id})
            if user_basic["user_state"] == 0:
                message["message_state"] = 0

            target_user_basic = await self.user_service.get_user_basic_mes({"user_id": message_to_id})
            message_target = {
                "messageToId": message_to_id,
                "messageToAvatar": target_user_basic["user_avatar"],
                "messageToName": target_user_basic["user_name"],
                "messageToState": target_user_basic["user_state"]
            }

            target_socket_id = (await self.socket_service.get_socket_mes({"_id": target_user_basic["user_socketId"]})).socket_id
            message_id = await self.message_service.create_message(message)
            await socket.emit(
                "messageFromFriend",
                {
                    "messageFromUser": {
                        "messageFromId": message_from_id,
                        "messageFromName": message_from_name,
                        "messageFromAvatar": message_from_avatar,
                        "messageFromState": message_from_state
                    },
                    "messageTarget": message_target,
                    "messageId": message_id,
                    "messageContent": message_content,
                    "messageContentType": message_content_type,
                    "messageType": message_type,
                    "messageCreatedTime": message["message_created_time"],
                },to=target_socket_id, namespace="/websocket"
            )

        # 群聊
        elif message_type == 1:
            if not await self._group_service.check_group_exists({"group_id": message_to_id}):
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail="目标群组不存在"
                )

            group_basic = await self._group_service.get_group_mes({"group_id": message_to_id})
            message_target = {
                "messageToId": message_to_id,
                "messageToAvatar": group_basic.group_avatar,
                "messageToName": group_basic.group_name,
                "messageToState": 1
            }

            message_id = await self.message_service.create_message(message)
            await socket.emit(
                "groupMemberMessage",
                {
                    "messageFromUser": {
                        "messageFromId": message_from_id,
                        "messageFromName": message_from_name,
                        "messageFromAvatar": message_from_avatar,
                        "messageFromState": message_from_state,
                    },
                    "messageTarget": message_target,
                    "messageId": message_id,
                    "messageContent": message_content,
                    "messageContentType": message_content_type,
                    "messageType": message_type,
                    "messageCreatedTime": message["message_created_time"]
                }, room=group_basic.group_name, namespace="/websocket"
            )

        # 更新对话表
        await self.dialog_service.update_dialog_mes(
            {"dialog_from_id": message_from_id, "dialog_target_id": message_to_id},
            {
                "dialog_id": None,
                "dialog_from_id": message_from_id,
                "dialog_target_id": message_to_id,
                "last_message_id": message_id,
                "dialog_last_time": message["message_created_time"]
            },
            {"last_message_id": message_id, "dialog_last_time": message["message_created_time"]}
        )

        if message_type == 0:
            await self.dialog_service.update_dialog_mes(
                {"dialog_from_id": message_to_id, "dialog_target_id": message_from_id},
                {
                    "dialog_id": None,
                    "dialog_from_id": message_to_id,
                    "dialog_target_id": message_from_id,
                    "last_message_id": message_id,
                    "dialog_last_time": message["message_created_time"]
                },
                {"last_message_id": message_id, "dialog_last_time": message["message_created_time"]}
            )
        else:
            group_members = await self.group_service.get_group_member_ids(message_to_id)
            for member_id in group_members:
                await self.dialog_service.update_dialog_mes(
                    {"dialog_from_id": member_id, "dialog_target_id": message_to_id},
                    {
                        "dialog_id": None,
                        "dialog_from_id": member_id,
                        "dialog_target_id": message_to_id,
                        "last_message_id": message_id,
                        "dialog_last_time": message["message_created_time"]
                    },
                    {"last_message_id": message_id, "dialog_last_time": message["message_created_time"]}
                )

        return {
            "error_code": 0,
            "data": {
                "message": "消息已成功发送",
                "chatingMessageMes": {
                    "messageFromUser": {
                        "messageFromId": message_from_id,
                        "messageFromName": message_from_name,
                        "messageFromAvatar": message_from_avatar,
                        "messageFromState": message_from_state
                    },
                    "messageTarget": message_target,
                    "messageId": message_id,
                    "messageContent": message_content,
                    "messageContentType": message_content_type,
                    "messageType": message_type,
                    "messageCreatedTime": message["message_created_time"]
                }
            }
        }

    async def get_last_message_mes_by_option(self, option: dict) -> Message:
        messages = await self.message_service.find_message_by_option(
            {"where": option, "order": {"message_created_time": "DESC"}, "skip": 0, "take": 1}
        )
        return messages[0] if messages else None

    async def get_messages_by_option(self, option: dict) -> List[Message]:
        return await self.message_service.find_message_by_option(option)

    async def get_history_message_by_target_type(self, dialog_target_type: str, dialog: dict, extra_option: Optional[Dict] = None) -> List[Message]:
        dialog_from_id, dialog_target_id = dialog.dialog_from_id, dialog.dialog_target_id
        user_option = {
            "where": [
                {"message_from_id": dialog_from_id, "message_to_id": dialog_target_id},
                {"message_from_id": dialog_target_id, "message_to_id": dialog_from_id}
            ]
        }
        group_option = {"where": {"message_to_id": dialog_target_id}}
        if extra_option:
            user_option = {**user_option, **extra_option}
            group_option = {**group_option, **extra_option}
        if dialog_target_type == "user":
            return await self.get_messages_by_option(user_option)
        else:
            return await self.get_messages_by_option(group_option)

    async def resolve_history_message(self, history_messages: List[Message]) -> List[dict]:
        resolved_messages = []
        for message in history_messages:
            message_from_id, message_to_id = message.message_from_id, message.message_to_id
            message_type = message.message_type

            # 私聊
            if message_type == 0:
                message_from_basic = await self.user_service.get_user_basic_mes({"user_id": message_from_id})
                message_to_basic = await self.user_service.get_user_basic_mes({"user_id": message_to_id})

                message_to_basic = {
                    "targetId": message_to_basic["user_id"],
                    "targetName": message_to_basic["user_name"],
                    "targetAvatar": message_to_basic["user_avatar"],
                    "targetState": message_to_basic["user_state"]
                }
            else:
                message_from_basic = await self.user_service.get_user_basic_mes({"user_id": message_from_id})
                message_to_basic = await self._group_service.get_group_mes({"group_id": message_to_id})

                message_to_basic = {
                    "targetId": message_to_basic.group_id,
                    "targetName": message_to_basic.group_name,
                    "targetAvatar": message_to_basic.group_avatar,
                    "targetState": 1
                }

            message_from_basic = {
                "fromId": message_from_basic["user_id"],
                "fromName": message_from_basic["user_name"],
                "fromAvatar": message_from_basic["user_avatar"],
                "fromState": message_from_basic["user_state"]
            }

            resolved_messages.append({
                "messageId": message.message_id,
                "messageFromMes": message_from_basic,
                "messageToMes": message_to_basic,
                "messageType": message.message_type,
                "messageContent": message.message_content,
                "messageContentType": message.message_content_type,
                "messageCreatedTime": message.message_created_time,
                "messageState": message.message_state
            })

        return resolved_messages
